package com.koo.modules.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.koo.common.utils.MyStrUtil;
import com.koo.common.utils.PageUtils;
import com.koo.common.utils.Query;
import com.koo.modules.product.dao.ProductCategoryDao;
import com.koo.modules.product.entity.ProductCategoryEntity;
import com.koo.modules.product.entity.vo.CategoryVo;
import com.koo.modules.product.service.ProductCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class ProductCategoryServiceImpl extends ServiceImpl<ProductCategoryDao, ProductCategoryEntity> implements ProductCategoryService {


    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        Object key = params.get("key");
        LambdaQueryWrapper<ProductCategoryEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(MyStrUtil.isNotEmpty(key), ProductCategoryEntity::getCategoryName, key);

        IPage<ProductCategoryEntity> page = this.page(
                new Query<ProductCategoryEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }


    @Override
    public PageUtils listTree(Map<String, Object> params) {
        LambdaQueryWrapper<ProductCategoryEntity> wrapper = new LambdaQueryWrapper<ProductCategoryEntity>();
        wrapper.orderByAsc(ProductCategoryEntity::getSort);
        wrapper.like(params.get("key") != null, ProductCategoryEntity::getCategoryName, params.get("key"));

        IPage<ProductCategoryEntity> page = this.page(
                new Query<ProductCategoryEntity>().getPage(params),
                wrapper
        );

        if (MyStrUtil.isEmpty(params.get("key"))) {
            List<ProductCategoryEntity> levelMenus = getTreeCategories(page.getRecords());

            Integer total = page.getRecords().stream()
                    .filter(e -> e.getParentId() == 0).collect(Collectors.toList()).size();

            page.setRecords(levelMenus);
            page.setTotal(total);
        }
        return new PageUtils(page);
    }

    @Override
    public List<CategoryVo> getTreeData() {
        LambdaQueryWrapper<ProductCategoryEntity> wrapper = new LambdaQueryWrapper();
        wrapper.lt(ProductCategoryEntity::getCatLevel, 3);
        List<ProductCategoryEntity> list = baseMapper.selectList(null);

        //1、转换为需要的格式
        List<CategoryVo> categoryVos = list.stream().map(item -> {
            //保存时按 键值和名称一起保存到value中，添加或更新的时候进行切割保存到 categoryId与categoryName中
            String value = item.getCategoryId() + ":" + item.getCategoryName();
            CategoryVo cate = new CategoryVo(item.getCategoryId(), item.getParentId(), item.getCategoryName(), value);
            cate.setSort(item.getSort());
            return cate;
        }).collect(Collectors.toList());

        //2、生成树形类别
        List<CategoryVo> levelCatories = categoryVos.stream()
                .filter(e -> e.getParentId() == 0)
                .map((cata) -> {
                    cata.setChildren(getMenuChildrens(cata, categoryVos));
                    return cata;
                })
                .sorted((cata1, cata2) -> {
                    return (cata1.getSort() == null ? 0 : cata1.getSort()) - (cata2.getSort() == null ? 0 : cata2.getSort());
                })
                .collect(Collectors.toList());
        return levelCatories;
    }

    @Override
    public List<ProductCategoryEntity> getTree(Integer level) {
        LambdaQueryWrapper<ProductCategoryEntity> wrapper = new LambdaQueryWrapper();
        wrapper.le(level != null, ProductCategoryEntity::getCatLevel, level);
        List<ProductCategoryEntity> list = baseMapper.selectList(wrapper);
        //2、生成树形类别
        return this.getTreeCategories(list);
    }

    /**
     * 更新时，必须更新旗下的所有的
     *
     * @param baseProductCategory
     */
    @Override
    public void updateStatus(ProductCategoryEntity baseProductCategory) {
        List<ProductCategoryEntity> list = baseMapper.listAllChildren(baseProductCategory.getCategoryId());
        list = list.stream().map(item -> {
            item.setStatus(baseProductCategory.getStatus());
            return item;
        }).collect(Collectors.toList());
        //批量更新
        this.updateBatchById(list);
    }

    @Override
    public ProductCategoryEntity info(String categoryId) {
        ProductCategoryEntity categoryEntity = this.getById(categoryId);
        Set<Long> selectIds = new HashSet<Long>();

        Integer catLevel = categoryEntity.getCatLevel();
        if(catLevel == 3){
            //获得一级 id
            ProductCategoryEntity parent = baseMapper.selectById(categoryEntity.getParentId());
            selectIds.add(parent.getParentId());
        }
        selectIds.add(categoryEntity.getParentId());
        categoryEntity.setSelectIds(selectIds);
        return categoryEntity;
    }

    public List<ProductCategoryEntity> childMenu = new ArrayList<>();//全局变量

    //递归查询所有子节点
    public List<ProductCategoryEntity> treeMenuList(List<ProductCategoryEntity> menuList, String myId) {
        if (MyStrUtil.isNotEmpty(myId) && CollectionUtils.isNotEmpty(menuList)) {
            for (ProductCategoryEntity mu : menuList) {
                //遍历出父id等于参数的id，add进子节点集合
                if (String.valueOf(mu.getParentId()).equals(myId)) {
                    //递归遍历下一级
                    childMenu.add(mu);
                    treeMenuList(menuList, mu.getCategoryId().toString());
                }
            }
        }
        return childMenu;
    }


    public List<ProductCategoryEntity> getTreeCategories(List<ProductCategoryEntity> entities) {
        List<ProductCategoryEntity> levelMenus = entities.stream()
                .filter(e -> e.getParentId() == 0)
                .map((category) -> {
                    category.setChildren(getCateChildrens(category, entities));
                    return category;
                })
                .sorted((cate1, cate2) -> {
                    return (cate1.getSort() == null ? 0 : cate1.getSort()) - (cate2.getSort() == null ? 0 : cate2.getSort());
                })
                .collect(Collectors.toList());
        return levelMenus;
    }

    private List<ProductCategoryEntity> getCateChildrens(ProductCategoryEntity root, List<ProductCategoryEntity> all) {
        List<ProductCategoryEntity> children = all.stream().filter(categoryEntity -> {
            return categoryEntity.getParentId().equals(root.getCategoryId());
        }).map(categoryEntity -> {
            //1、找到子菜单(递归)
            if (CollectionUtils.isNotEmpty(getCateChildrens(categoryEntity, all))) {
                categoryEntity.setChildren(getCateChildrens(categoryEntity, all));
            }
            return categoryEntity;
        }).sorted((cata1, cata2) -> {
            //2、菜单的排序
            return (cata1.getSort() == null ? 0 : cata1.getSort()) - (cata2.getSort() == null ? 0 : cata2.getSort());
        }).collect(Collectors.toList());
        return children;
    }


    private List<CategoryVo> getMenuChildrens(CategoryVo root, List<CategoryVo> all) {

        List<CategoryVo> children = all.stream().filter(categoryEntity -> {
            return categoryEntity.getParentId().equals(root.getId());
        }).map(categoryEntity -> {
            //1、找到子菜单(递归)
            if (CollectionUtils.isNotEmpty(getMenuChildrens(categoryEntity, all))) {
                categoryEntity.setChildren(getMenuChildrens(categoryEntity, all));
            }
            return categoryEntity;
        }).sorted((cata1, cata2) -> {
            //2、菜单的排序
            return (cata1.getSort() == null ? 0 : cata1.getSort()) - (cata2.getSort() == null ? 0 : cata2.getSort());
        }).collect(Collectors.toList());
        return children;

    }
}